#include <bits/stdc++.h>

using std::swap;
using std::max;

struct iostream
{
	const static int bufsiz=1500000;
	char inbuf[bufsiz],oubuf[bufsiz];
	int inp,oup;
	iostream():inp(bufsiz),oup(0){}
	inline iostream& operator >> (char &c){
		static int end=bufsiz;
		if(end==bufsiz) end=fread(inbuf,1,bufsiz,stdin),inp=0;
		if(!end) c=EOF;
		else c=inbuf[inp++];
		return *this;
	}
	template <typename T>  inline iostream& operator >> (T &r){
		char c;bool f=0;
		for(*this>>c;c>'9'||c<'0';*this>>c) if(c=='-') f=1;
		for(r=0;c<='9'&&c>='0';*this>>c) r=r*10+c-'0';
		if(f) r=-r;
		return *this;
	}
	inline iostream& operator << (char c){
		oubuf[oup++]=c;
		if(oup==bufsiz) fwrite(oubuf,bufsiz,1,stdout),oup=0;
		return *this;
	}
	template <typename T> inline iostream& operator << (T r){
		static int sta[50];int len=0;
		if(r<0){*this<<'-';r=-r;}
		while(r) sta[len++]=r%10,r/=10;
		if(!len) sta[len++]=0;
		while(len--) *this<<(char)(sta[len]+'0');
		return *this;
	}
	~iostream(){
		fwrite(oubuf,oup,1,stdout);
	}
};
struct Query
{
	int f,x,y;
	Query(const int &_f=0,const int &_x=0,const int &_y=0):f(_f),x(_x),y(_y){
		if(f/2>1){
			f-=2;
			swap(x,y);
		}
	}
};

const int maxn=100005;

int v[maxn*3],w[maxn*3],g[maxn],nxt[maxn*3];
int cnt[maxn],fa[maxn],dis[maxn];
Query q[maxn];int que[maxn];
bool inq[maxn];
iostream io;

int find(const int &x){return fa[x]==x?x:fa[x]=find(fa[x]);}
template <typename T> inline bool update(T &x,T y){if(y>x) return x=y,true;return false;}

int main(){
	int n,k,qn;
	int f,r;

	freopen("2330.in","r",stdin);
	freopen("2330.out","w",stdout);

	qn=0;
	memset(g,-1,sizeof(g));
	io>>n>>k;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=0;i<k;i++){
		int f,x,y;
		io>>f>>x>>y;
		if(f==1) fa[find(x)]=find(y);
		else q[qn++]=Query(f,x,y);
	}
	for(int i=0;i<qn;i++){
		int a,b;
		a=find(q[i].x);b=find(q[i].y);
		if(q[i].f==2){
			if(a==b){
				io<<-1<<'\n';
				return 0;
			}
			v[i]=b;nxt[i]=g[a];g[a]=i;w[i]=1;
		}else if(a!=b){
			swap(a,b);
			v[i]=b;nxt[i]=g[a];g[a]=i;w[i]=0;
		}
	}

	f=r=0;
	for(int i=1;i<=n;i++) if(fa[i]==i) que[r++]=i,dis[i]=cnt[i]=1;
	while(f!=r){
		const int &cur=que[f];
		for(int j=g[cur];~j;j=nxt[j]){
			const int &tar=v[j];
			if(update(dis[tar],dis[cur]+w[j])){
				if(cnt[tar]++>n){
					io<<-1<<'\n';
					return 0;
				}
				if(!inq[tar]){
					que[r++]=tar;
					if(r==maxn) r=0;
					inq[tar]=1;
				}
			}
		}
		inq[cur]=0;
		f++;
		if(f==maxn) f=0;
	}

	long long ans=0;
	for(int i=1;i<=n;i++) ans+=dis[find(i)];
	io<<ans<<'\n';
	return 0;
}